/*
 * @Author: Suo-Yuheng syh15399227325@163.com
 * @Date: 2025-09-23 11:16:46
 * @LastEditors: Suo-Yuheng syh15399227325@163.com
 * @LastEditTime: 2025-09-23 15:39:18
 * @FilePath: /0923/Epoller.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include "nocopy.hpp"
#include "log.hpp"
#include <sys/epoll.h>
#include <cstring>

class Epoller : public nocopy
{
    static const int size = 128;

public:
    Epoller()
    {
        _epfd = epoll_create(size);
        if (_epfd == -1)
        {
            lg(Error, "epoll_create error: %s", strerror(errno));
        }
        else
        {
            lg(Info, "epoll_create success: %d", _epfd);
        }
    }

    int EpollerWait(struct epoll_event revents[], int num) // 用输出型参数，交给上层决定
    {
        int n = epoll_wait(_epfd, revents, num, _timeout);
        return n;
    }

    int EpollerUpdate(int oper, int sock, uint32_t event) // 对 ctl 做个封装，根据epoll操作，调相关函数
    {
        int n = 0;
        if (oper == EPOLL_CTL_DEL)
        {
            n = epoll_ctl(_epfd, oper, sock, nullptr);
            if (n != 0)
            {
                lg(Error, "eopll_ctl delete error!");
            }
        }
        else // EPOLL_CTL_MOD  ||  EPOLL_CTL_ADD
        {
            struct epoll_event ev;
            ev.events = event;
            ev.data.fd = sock; // 方便后续明白，就绪的 是哪个 fd

            n = epoll_ctl(_epfd, oper, sock, &ev); // 把用户层已经填充好的 fd、事件类型，用 接口 注册进去
            if (n != 0)
            {
                lg(Error, "eopll_ctl error!");
            }
        }
        return n;
    }

    ~Epoller()
    {
        if (_epfd >= 0)
            close(_epfd);
    }

private:
    int _epfd;
    int _timeout{3000};
};